#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/major.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/vmalloc.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/time.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/wait.h>
#include <asm-generic/errno-base.h>
#include "../CCP907_SEC_MODULE/INCLUDE/compate.h"
#include "../CCP907_SEC_MODULE/INCLUDE/pci_csec.h"
#include "../CCP907_SEC_MODULE/INCLUDE/desc.h"
#include "../CCP907_SEC_MODULE/INCLUDE/desc_constr.h"
#include "../CCP907_SEC_MODULE/INCLUDE/sm2_job.h"
#include "../CCP907_SEC_MODULE/INCLUDE/rsa_job.h"
#include "../CCP907_SEC_MODULE/INCLUDE/sm9.h"
#include "asym.h"

void sm2_genkey_res_free(struct csec_priv_t *csec_priv, struct asym_resource *asym_res)
{
	if(memcmp(asym_res->sm2_gk_res.ctrl_data,
			asym_res->sm2_gk_res.pub_key,
			asym_res->sm2_gk_res.pub_key_len)) {
		csec_debug3(KERN_INFO "SM2 GENKEY failed!\n");
	}else
		csec_debug3(KERN_INFO "SM2 GENKEY successfully!\n");
		
#if ASYN_OUTPUT_DUMP
	print_hex_dump(KERN_CONT, "PUBK", DUMP_PREFIX_OFFSET, 16, 1,
				asym_res->sm2_gk_res.pub_key,
				asym_res->sm2_gk_res.pub_key_len, true);
	print_hex_dump(KERN_CONT, "CTRL", DUMP_PREFIX_OFFSET, 16, 1,
				asym_res->sm2_gk_res.ctrl_data,
				asym_res->sm2_gk_res.pub_key_len, true);
#endif					
	dma_free_coherent(csec_priv->dev, asym_res->sm2_gk_res.fp256_param_len,
						asym_res->sm2_gk_res.fp256_param,
						asym_res->sm2_gk_res.fp256_param_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_gk_res.pub_key_len,
						asym_res->sm2_gk_res.pub_key,
						asym_res->sm2_gk_res.pub_key_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_gk_res.pri_key_len,
						asym_res->sm2_gk_res.pri_key,
						asym_res->sm2_gk_res.pri_key_dma);
	kfree(asym_res->sm2_gk_res.ctrl_data);

}
void sm2_encrypt_res_free(struct csec_priv_t *csec_priv, struct asym_resource *asym_res)
{
	if(memcmp(asym_res->sm2_enc_res.ctrl_data+1,
			asym_res->sm2_enc_res.c+1,
			asym_res->sm2_enc_res.c_len-1)) {
		csec_debug3(KERN_INFO "SM2 ENCRYPT failed!\n");
	} else 
		csec_debug3(KERN_INFO "SM2 ENCRYPT successfully!\n");

#if ASYN_OUTPUT_DUMP
	print_hex_dump(KERN_CONT, "OUTP:", DUMP_PREFIX_OFFSET, 16, 1,
				asym_res->sm2_enc_res.c,
				asym_res->sm2_enc_res.c_len, true);
	print_hex_dump(KERN_CONT, "CTRL:", DUMP_PREFIX_OFFSET, 16, 1,
				asym_res->sm2_enc_res.ctrl_data,
				asym_res->sm2_enc_res.c_len, true);
#endif					

	dma_free_coherent(csec_priv->dev, asym_res->sm2_enc_res.fp256_param_len,
						asym_res->sm2_enc_res.fp256_param,
						asym_res->sm2_enc_res.fp256_param_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_enc_res.pub_key_len,
						asym_res->sm2_enc_res.pub_key,
						asym_res->sm2_enc_res.pub_key_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_enc_res.msg_len,
						asym_res->sm2_enc_res.msg,
						asym_res->sm2_enc_res.msg_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_enc_res.c_len,
						asym_res->sm2_enc_res.c,
						asym_res->sm2_enc_res.c_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_enc_res.hashin_len,
						asym_res->sm2_enc_res.hashin,
						asym_res->sm2_enc_res.hashin_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_enc_res.k_len,
						asym_res->sm2_enc_res.k,
						asym_res->sm2_enc_res.k_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_enc_res.ct_len,
						asym_res->sm2_enc_res.ct,
						asym_res->sm2_enc_res.ct_dma);
	kfree(asym_res->sm2_enc_res.ctrl_data);

}
void sm2_decrypt_res_free(struct csec_priv_t *csec_priv, struct asym_resource *asym_res)
{
	if(memcmp(asym_res->sm2_dec_res.ctrl_data,
			asym_res->sm2_dec_res.msg,
			asym_res->sm2_dec_res.msg_len)) {
		csec_debug3(KERN_INFO "SM2 DECRYPT failed!\n");
	} else 
		csec_debug3(KERN_INFO "SM2 DECRYPT successfully!\n");

#if ASYN_OUTPUT_DUMP
	print_hex_dump(KERN_CONT, "OUTP:", DUMP_PREFIX_OFFSET, 16, 1,
				asym_res->sm2_dec_res.msg,
				asym_res->sm2_dec_res.msg_len, true);
	print_hex_dump(KERN_CONT, "CTRL:", DUMP_PREFIX_OFFSET, 16, 1,
				asym_res->sm2_dec_res.ctrl_data,
				asym_res->sm2_dec_res.msg_len, true);
#endif					

	dma_free_coherent(csec_priv->dev, asym_res->sm2_dec_res.fp256_param_len,
						asym_res->sm2_dec_res.fp256_param,
						asym_res->sm2_dec_res.fp256_param_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_dec_res.pri_key_len,
						asym_res->sm2_dec_res.pri_key,
						asym_res->sm2_dec_res.pri_key_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_dec_res.msg_len,
						asym_res->sm2_dec_res.msg,
						asym_res->sm2_dec_res.msg_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_dec_res.c_len,
						asym_res->sm2_dec_res.c,
						asym_res->sm2_dec_res.c_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_dec_res.hashin_len,
						asym_res->sm2_dec_res.hashin,
						asym_res->sm2_dec_res.hashin_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_dec_res.ct_len,
						asym_res->sm2_dec_res.ct,
						asym_res->sm2_dec_res.ct_dma);
	kfree(asym_res->sm2_dec_res.ctrl_data);

}
void sm2_signature_res_free(struct csec_priv_t *csec_priv, struct asym_resource *asym_res)
{
	if(memcmp(asym_res->sm2_sign_res.ctrl_data,
			asym_res->sm2_sign_res.r,
			asym_res->sm2_sign_res.r_len)) {
		csec_debug3(KERN_INFO "SM2 SIGNATURE R failed!\n");
	} else if(memcmp(asym_res->sm2_sign_res.ctrl_data
			+asym_res->sm2_sign_res.r_len,
			asym_res->sm2_sign_res.s,
			asym_res->sm2_sign_res.s_len)) {
		csec_debug3(KERN_INFO "SM2 SIGNATURE S failed!\n");
	} else
		csec_debug3(KERN_INFO "SM2 SIGNATURE successfully!\n");

#if ASYN_OUTPUT_DUMP
	print_hex_dump(KERN_CONT, "OUTR:", DUMP_PREFIX_OFFSET, 16, 1,
				asym_res->sm2_sign_res.r,
				asym_res->sm2_sign_res.r_len, true);
	print_hex_dump(KERN_CONT, "OUTS:", DUMP_PREFIX_OFFSET, 16, 1,
				asym_res->sm2_sign_res.s,
				asym_res->sm2_sign_res.s_len, true);
	print_hex_dump(KERN_CONT, "CTRL:", DUMP_PREFIX_OFFSET, 16, 1,
				asym_res->sm2_sign_res.ctrl_data,
				asym_res->sm2_sign_res.r_len*2, true);
#endif					

	dma_free_coherent(csec_priv->dev, asym_res->sm2_sign_res.fp256_param_len,
						asym_res->sm2_sign_res.fp256_param,
						asym_res->sm2_sign_res.fp256_param_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_sign_res.pri_key_len,
						asym_res->sm2_sign_res.pri_key,
						asym_res->sm2_sign_res.pri_key_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_sign_res.msg_len,
						asym_res->sm2_sign_res.msg,
						asym_res->sm2_sign_res.msg_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_sign_res.r_len,
						asym_res->sm2_sign_res.r,
						asym_res->sm2_sign_res.r_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_sign_res.s_len,
						asym_res->sm2_sign_res.s,
						asym_res->sm2_sign_res.s_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_sign_res.one_len,
						asym_res->sm2_sign_res.one,
						asym_res->sm2_sign_res.one_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_sign_res.k_len,
						asym_res->sm2_sign_res.k,
						asym_res->sm2_sign_res.k_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_sign_res.z_len,
						asym_res->sm2_sign_res.z,
						asym_res->sm2_sign_res.z_dma);
	kfree(asym_res->sm2_sign_res.ctrl_data);

}
void sm2_verify_res_free(struct csec_priv_t *csec_priv, struct asym_resource *asym_res)
{
	if(asym_res->result.rst)
		csec_debug3(KERN_INFO "SM2 VERIFY failed!\n");
	else
		csec_debug3(KERN_INFO "SM2 VERIFY successfully!\n");

	dma_free_coherent(csec_priv->dev, asym_res->sm2_veri_res.fp256_param_len,
						asym_res->sm2_veri_res.fp256_param,
						asym_res->sm2_veri_res.fp256_param_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_veri_res.pub_key_len,
						asym_res->sm2_veri_res.pub_key,
						asym_res->sm2_veri_res.pub_key_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_veri_res.msg_len,
						asym_res->sm2_veri_res.msg,
						asym_res->sm2_veri_res.msg_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_veri_res.r_len,
						asym_res->sm2_veri_res.r,
						asym_res->sm2_veri_res.r_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_veri_res.s_len,
						asym_res->sm2_veri_res.s,
						asym_res->sm2_veri_res.s_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_veri_res.one_len,
						asym_res->sm2_veri_res.one,
						asym_res->sm2_veri_res.one_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_veri_res.z_len,
						asym_res->sm2_veri_res.z,
						asym_res->sm2_veri_res.z_dma);

}
void sm2_exchange_res_free(struct csec_priv_t *csec_priv, struct asym_resource *asym_res)
{
	if(memcmp(asym_res->sm2_exch_res.ctrl_data,
			asym_res->sm2_exch_res.s1,
			asym_res->sm2_exch_res.s1_len)) {
		csec_debug3(KERN_INFO "SM2 EXCHANGE S1 failed!\n");
	} else if(memcmp(asym_res->sm2_exch_res.ctrl_data
			+asym_res->sm2_exch_res.s1_len,
			asym_res->sm2_exch_res.s2,
			asym_res->sm2_exch_res.s2_len)) {
		csec_debug3(KERN_INFO "SM2 EXCHANGE S2 failed!\n");
	} else
		csec_debug3(KERN_INFO "SM2 EXCHANGE successfully!\n");

#if ASYN_OUTPUT_DUMP
	print_hex_dump(KERN_CONT, "OUT1:", DUMP_PREFIX_OFFSET, 16, 1,
				asym_res->sm2_exch_res.s1,
				asym_res->sm2_exch_res.s1_len, true);
	print_hex_dump(KERN_CONT, "OUT2:", DUMP_PREFIX_OFFSET, 16, 1,
				asym_res->sm2_exch_res.s2,
				asym_res->sm2_exch_res.s2_len, true);
	print_hex_dump(KERN_CONT, "CTRL:", DUMP_PREFIX_OFFSET, 16, 1,
				asym_res->sm2_exch_res.ctrl_data,
				asym_res->sm2_exch_res.s1_len*2, true);
		
#endif
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.fp256_param_len,
						asym_res->sm2_exch_res.fp256_param,
						asym_res->sm2_exch_res.fp256_param_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.pri_key_len,
						asym_res->sm2_exch_res.pri_key,
						asym_res->sm2_exch_res.pri_key_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.hashin_len,
						asym_res->sm2_exch_res.hashin,
						asym_res->sm2_exch_res.hashin_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.hashout_len,
						asym_res->sm2_exch_res.hashout,
						asym_res->sm2_exch_res.hashout_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.ct_len,
						asym_res->sm2_exch_res.ct,
						asym_res->sm2_exch_res.ct_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.one_len,
						asym_res->sm2_exch_res.one,
						asym_res->sm2_exch_res.one_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.pub_key1_len,
						asym_res->sm2_exch_res.pub_key1,
						asym_res->sm2_exch_res.pub_key1_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.tmp_pub_key_len,
						asym_res->sm2_exch_res.tmp_pub_key,
						asym_res->sm2_exch_res.tmp_pub_key_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.tmp_pri_key_len,
						asym_res->sm2_exch_res.tmp_pri_key,
						asym_res->sm2_exch_res.tmp_pri_key_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.tmp_pub_key1_len,
						asym_res->sm2_exch_res.tmp_pub_key1,
						asym_res->sm2_exch_res.tmp_pub_key1_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.x1_len,
						asym_res->sm2_exch_res.x1,
						asym_res->sm2_exch_res.x1_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.x2_len,
						asym_res->sm2_exch_res.x2,
						asym_res->sm2_exch_res.x2_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.z1_len,
						asym_res->sm2_exch_res.z1,
						asym_res->sm2_exch_res.z1_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.z2_len,
						asym_res->sm2_exch_res.z2,
						asym_res->sm2_exch_res.z2_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.za_len,
						asym_res->sm2_exch_res.za,
						asym_res->sm2_exch_res.za_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.zb_len,
						asym_res->sm2_exch_res.zb,
						asym_res->sm2_exch_res.zb_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.key_len,
						asym_res->sm2_exch_res.key,
						asym_res->sm2_exch_res.key_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.s1_len,
						asym_res->sm2_exch_res.s1,
						asym_res->sm2_exch_res.s1_dma);
	dma_free_coherent(csec_priv->dev, asym_res->sm2_exch_res.s2_len,
						asym_res->sm2_exch_res.s2,
						asym_res->sm2_exch_res.s2_dma);
	kfree(asym_res->sm2_exch_res.ctrl_data);

}
void asym_callback_handler(struct csec_priv_t *csec_priv,void *desc_va,
				dma_addr_t desc_pa, uint32_t status, void *arg)
{	
	struct asym_resource *asym_res;
	asym_res = arg;
	asym_res->result.rst = status;

#if 1
	if(asym_res->result.sg_virt)
	{
		printk(KERN_INFO "%s scatter/gather work!\n",__func__);
		dma_unmap_single(csec_priv->dev,asym_res->result.sg_phy,SGMAX*16,DMA_TO_DEVICE);
		kfree(asym_res->result.sg_virt);
	}

	if(asym_res->algs == SM2) {
		switch(asym_res->type) {
			case GENKEY:
				sm2_genkey_res_free(csec_priv, asym_res);
				break;
			case ENCRYPT:
				sm2_encrypt_res_free(csec_priv, asym_res);
				break;
			case DECRYPT:
				sm2_decrypt_res_free(csec_priv, asym_res);
				break;
			case SIGN:
				sm2_signature_res_free(csec_priv, asym_res);
				break;
			case VERIFY:
				sm2_verify_res_free(csec_priv, asym_res);
				break;
			case EXCH:
				sm2_exchange_res_free(csec_priv, asym_res);
				break;
			defualt:
				break;
		}
	} else if(asym_res->algs == SM9) {
		/* Support in future*/
	} else if (asym_res->algs == RSA1024){
		/* Support in future*/
	} else if (asym_res->algs == RSA2048){
		/* Support in future*/
	}
	
#ifdef ASYN_MODE_BENCHMARK
	complete(asym_res->comp);
#endif
	dma_free_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, desc_va, desc_pa);
	kfree(asym_res);
#endif
}

void do_sm2_genkey_asyn(struct csec_priv_t *csec_priv,
			unsigned int *desc, dma_addr_t desc_dma,
			struct sm2_genkey_private_dma *para,
			struct asym_resource *asym_res)
{
	int status;

	inline_cnstr_jobdesc_sm2_genkey(desc, para);

	do
	{
		status = cards_enqueue(csec_priv, desc, desc_dma, asym_res->callback, asym_res);
		if(status)
		{
			if(CDEV_INVL)
			{
				//wait_event_timeout(csec_priv->ccore_cards->dq_done,0,CDEV_INVL);
				set_current_state(TASK_INTERRUPTIBLE);
				schedule_timeout(CDEV_INVL);
				
				csec_debug2(KERN_INFO "ce0\n");
			}
		}
	}while(status==-EBUSY);
}

void do_sm2_encrypt_asyn(struct csec_priv_t *csec_priv,
			unsigned int *desc, dma_addr_t desc_dma,
			struct sm2_enc_private_dma *para,
			struct asym_resource *asym_res)
{
	int status;

	inline_cnstr_jobdesc_sm2_encrypt(desc, para);

	do
	{
		status = cards_enqueue(csec_priv,  desc, desc_dma, asym_res->callback, asym_res);
		if(status)
		{
			if(CDEV_INVL)
			{
				//wait_event_timeout(csec_priv->ccore_cards->dq_done,0,CDEV_INVL);
				set_current_state(TASK_INTERRUPTIBLE);
				schedule_timeout(CDEV_INVL);
				
				csec_debug2(KERN_INFO "ce0\n");
			}
		}
	}while(status==-EBUSY);
}

void do_sm2_decrypt_asyn(struct csec_priv_t *csec_priv,
		unsigned int *desc, dma_addr_t desc_dma,
		struct sm2_dec_private_dma *para,
		struct asym_resource *asym_res)
{
	int status;

	inline_cnstr_jobdesc_sm2_decrypt(desc, para);

	do
	{
		status = cards_enqueue(csec_priv,  desc, desc_dma,asym_res->callback, asym_res);
		if(status)
		{
			if(CDEV_INVL)
			{
				//wait_event_timeout(csec_priv->ccore_cards->dq_done,0,CDEV_INVL);
				set_current_state(TASK_INTERRUPTIBLE);
				schedule_timeout(CDEV_INVL);
				
				csec_debug2(KERN_INFO "ce0\n");
			}
		}
	}while(status==-EBUSY);
}

void do_sm2_signature_asyn(struct csec_priv_t *csec_priv,
		unsigned int *desc, dma_addr_t desc_dma,
		struct sm2_sig_private_dma *para,
		struct asym_resource *asym_res)
{
	int status;

	inline_cnstr_jobdesc_sm2_signature(desc, para);

	do
	{
		status = cards_enqueue(csec_priv, desc, desc_dma, asym_res->callback, asym_res);
		if(status)
		{
			if(CDEV_INVL)
			{
				//wait_event_timeout(csec_priv->ccore_cards->dq_done,0,CDEV_INVL);
				set_current_state(TASK_INTERRUPTIBLE);
				schedule_timeout(CDEV_INVL);
				
				csec_debug2(KERN_INFO "ce0\n");
			}
		}
	}while(status==-EBUSY);

}

void do_sm2_verify_asyn(struct csec_priv_t *csec_priv,
		unsigned int *desc, dma_addr_t desc_dma,
		struct sm2_ver_private_dma *para,
		struct asym_resource *asym_res)
{
	int status;

	inline_cnstr_jobdesc_sm2_verify(desc, para);

	do
	{
		status = cards_enqueue(csec_priv, desc, desc_dma, asym_res->callback, asym_res);
		if(status)
		{
			if(CDEV_INVL)
			{
				//wait_event_timeout(csec_priv->ccore_cards->dq_done,0,CDEV_INVL);
				set_current_state(TASK_INTERRUPTIBLE);
				schedule_timeout(CDEV_INVL);
				
				csec_debug2(KERN_INFO "ce0\n");
			}
		}
	}while(status==-EBUSY);

}

void do_sm2_exchange_asyn(struct csec_priv_t *csec_priv,
		unsigned int *desc, dma_addr_t desc_dma,
		struct sm2_exc_private_dma *para,
		struct asym_resource *asym_res)
{
	int status;

	inline_cnstr_jobdesc_sm2_exchange(desc, para);

	do
	{
		status = cards_enqueue(csec_priv, desc, desc_dma, asym_res->callback, asym_res);
		if(status)
		{
			if(CDEV_INVL)
			{
				//wait_event_timeout(csec_priv->ccore_cards->dq_done,0,CDEV_INVL);
				set_current_state(TASK_INTERRUPTIBLE);
				schedule_timeout(CDEV_INVL);
				
				csec_debug2(KERN_INFO "ce0\n");
			}
		}
	}while(status==-EBUSY);

}
int sm2_genkey_thread_asyn(void *para)
{
	struct sm2_genkey_private_dma st_genkey;

	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);
	struct asym_resource *asym_res;

	unsigned char s_pria[32] = {
		0x6F, 0xCB, 0xA2, 0xEF, 0x9A, 0xE0, 0xAB, 0x90, 0x2B, 0xC3, 0xBD, 0xE3, 0xFF, 0x91, 0x5D, 0x44, 
		0xBA, 0x4C, 0xC7, 0x8F, 0x88, 0xE2, 0xF8, 0xE7, 0xF8, 0x99, 0x6D, 0x3B, 0x8C, 0xCE, 0xED, 0xEE	
	};
	unsigned char s_puba[64] = {                                                                                      
		0x30, 0x99, 0x09, 0x3B, 0xF3, 0xC1, 0x37, 0xD8, 0xFC, 0xBB, 0xCD, 0xF4, 0xA2, 0xAE, 0x50, 0xF3,           
		0xB0, 0xF2, 0x16, 0xC3, 0x12, 0x2D, 0x79, 0x42, 0x5F, 0xE0, 0x3A, 0x45, 0xDB, 0xFE, 0x16, 0x55,           
		0x3D, 0xF7, 0x9E, 0x8D, 0xAC, 0x1C, 0xF0, 0xEC, 0xBA, 0xA2, 0xF2, 0xB4, 0x9D, 0x51, 0xA4, 0xB3,           
		0x87, 0xF2, 0xEF, 0xAF, 0x48, 0x23, 0x39, 0x08, 0x6A, 0x27, 0xA8, 0xE0, 0x5B, 0xAE, 0xD9, 0x8B	   
	};

	unsigned char *fp256_param, *pub_key, *pri_key;
	unsigned int *desc;
	dma_addr_t fp256_param_dma, desc_dma, pub_key_dma, pri_key_dma;

	fp256_param = dma_alloc_coherent(csec_priv->dev, 224, &fp256_param_dma, GFP_KERNEL | GFP_DMA);
	pub_key = dma_alloc_coherent(csec_priv->dev, 32*2, &pub_key_dma, GFP_KERNEL | GFP_DMA);
	pri_key = dma_alloc_coherent(csec_priv->dev, 32, &pri_key_dma, GFP_KERNEL | GFP_DMA);
	desc = dma_alloc_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, &desc_dma, GFP_KERNEL | GFP_DMA);
	if(!pri_key)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	asym_res = kzalloc(sizeof(struct asym_resource),GFP_KERNEL);
	if(!asym_res)
	{
		csec_error(KERN_INFO "struct asym_resource kzalloc error\n");
		return -EINVAL;
	}
	memcpy(fp256_param, sm2_fp_param1, 224);
	memcpy(pri_key, s_pria, 32);

	//generate key pair
	st_genkey.ecc_dma.p = fp256_param_dma;
	st_genkey.ecc_dma.a = fp256_param_dma+32;
	st_genkey.ecc_dma.b = fp256_param_dma+32*2;
	st_genkey.ecc_dma.gx = fp256_param_dma+32*3;
	st_genkey.ecc_dma.gy = fp256_param_dma+32*4;
	st_genkey.ecc_dma.n = fp256_param_dma+32*5;
	st_genkey.pubkey_dma.x = pub_key_dma;
	st_genkey.pubkey_dma.y = pub_key_dma+32;
	st_genkey.prikey_dma = pri_key_dma;
	st_genkey.plen = 32;
	st_genkey.nlen = 32;
	st_genkey.ecc_mode = FP;
	st_genkey.rng_mode = CONSTANT;

	asym_res->algs = SM2;
	asym_res->type = GENKEY; 
	asym_res->sm2_gk_res.fp256_param = fp256_param;
	asym_res->sm2_gk_res.pub_key = pub_key;
	asym_res->sm2_gk_res.pri_key = pri_key;
	asym_res->sm2_gk_res.fp256_param_dma = fp256_param_dma;
	asym_res->sm2_gk_res.pub_key_dma = pub_key_dma;
	asym_res->sm2_gk_res.pri_key_dma = pri_key_dma;
	asym_res->sm2_gk_res.fp256_param_len = 224;
	asym_res->sm2_gk_res.pub_key_len = 32*2;
	asym_res->sm2_gk_res.pri_key_len = 32;

	asym_res->comp = para;
	asym_res->sm2_gk_res.ctrl_data = kzalloc(asym_res->sm2_gk_res.pub_key_len, GFP_KERNEL);
	if(!asym_res->sm2_gk_res.ctrl_data)
	{
		csec_error(KERN_INFO "%s: control data buffer kzalloc error\n",__func__);
		return -EINVAL;
	}
	memcpy(asym_res->sm2_gk_res.ctrl_data,
			s_puba, asym_res->sm2_gk_res.pub_key_len);
	asym_res->callback = (void *)asym_callback_handler;

	do_sm2_genkey_asyn(csec_priv, desc, desc_dma, &st_genkey, asym_res);

#ifndef ASYN_MODE_BENCHMARK
	complete(this);
#endif
	return 0;
}

int sm2_encrypt_thread_asyn(void *para)
{
	struct sm2_enc_private_dma st_enc;

	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);
	struct asym_resource *asym_res;

	unsigned char standard_mes[19] =
	{
		0x65, 0x6E, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x73,0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64
	};

	unsigned char s_puba[64] = 
	{                                                                                      
		0x43, 0x5B, 0x39, 0xCC, 0xA8, 0xF3, 0xB5, 0x08, 0xC1, 0x48, 0x8A, 0xFC, 0x67, 0xBE, 0x49, 0x1A,
		0x0F, 0x7B, 0xA0, 0x7E, 0x58, 0x1A, 0x0E, 0x48, 0x49, 0xA5, 0xCF, 0x70, 0x62, 0x8A, 0x7E, 0x0A,
		0x75, 0xDD, 0xBA, 0x78, 0xF1, 0x5F, 0xEE, 0xCB, 0x4C, 0x78, 0x95, 0xE2, 0xC1, 0xCD, 0xF5, 0xFE,
		0x01, 0xDE, 0xBB, 0x2C, 0xDB, 0xAD, 0xF4, 0x53, 0x99, 0xCC, 0xF7, 0x7B, 0xBA, 0x07, 0x6A, 0x42
	};

	unsigned char rng_k[32] = 
	{
		0x4C, 0x62, 0xEE, 0xFD, 0x6E, 0xCF, 0xC2, 0xB9, 0x5B, 0x92, 0xFD, 0x6C, 0x3D, 0x95, 0x75, 0x14,
		0x8A, 0xFA, 0x17, 0x42, 0x55, 0x46, 0xD4, 0x90, 0x18, 0xE5, 0x38, 0x8D, 0x49, 0xDD, 0x7B, 0x4F
	};

	unsigned char cipher_text[116] = {
		0x04, 0x24, 0x5C, 0x26, 0xFB, 0x68, 0xB1, 0xDD, 0xDD, 0xB1, 0x2C, 0x4B, 0x6B, 0xF9, 0xF2, 0xB6,
		0xD5, 0xFE, 0x60, 0xA3, 0x83, 0xB0, 0xD1, 0x8D, 0x1C, 0x41, 0x44, 0xAB, 0xF1, 0x7F, 0x62, 0x52,
		0xE7, 0x76, 0xCB, 0x92, 0x64, 0xC2, 0xA7, 0xE8, 0x8E, 0x52, 0xB1, 0x99, 0x03, 0xFD, 0xC4, 0x73,
		0x78, 0xF6, 0x05, 0xE3, 0x68, 0x11, 0xF5, 0xC0, 0x74, 0x23, 0xA2, 0x4B, 0x84, 0x40, 0x0F, 0x01,
		0xB8, 0x65, 0x00, 0x53, 0xA8, 0x9B, 0x41, 0xC4, 0x18, 0xB0, 0xC3, 0xAA, 0xD0, 0x0D, 0x88, 0x6C,
		0x00, 0x28, 0x64, 0x67, 0x9C, 0x3D, 0x73, 0x60, 0xC3, 0x01, 0x56, 0xFA, 0xB7, 0xC8, 0x0A, 0x02,
		0x76, 0x71, 0x2D, 0xA9, 0xD8, 0x09, 0x4A, 0x63, 0x4B, 0x76, 0x6D, 0x3A, 0x28, 0x5E, 0x07, 0x48,
		0x06, 0x53, 0x42, 0x6D
	};

	unsigned char *fp256_param, *pub_key, *msg, *c, *hashin, *k;
//	unsigned char , *hashout;
	unsigned int *desc, *ct;
	dma_addr_t fp256_param_dma, desc_dma, pub_key_dma, msg_dma, c_dma, hashin_dma, ct_dma, k_dma;

	fp256_param = dma_alloc_coherent(csec_priv->dev, 224, &fp256_param_dma, GFP_KERNEL | GFP_DMA);
	pub_key = dma_alloc_coherent(csec_priv->dev, 32*2, &pub_key_dma, GFP_KERNEL | GFP_DMA);
	desc = dma_alloc_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, &desc_dma, GFP_KERNEL | GFP_DMA);
	msg = dma_alloc_coherent(csec_priv->dev, 19, &msg_dma, GFP_KERNEL | GFP_DMA);
	c = dma_alloc_coherent(csec_priv->dev, 1+32*2+19+32, &c_dma, GFP_KERNEL | GFP_DMA);
	hashin = dma_alloc_coherent(csec_priv->dev, 32*2+4, &hashin_dma, GFP_KERNEL | GFP_DMA);
	k = dma_alloc_coherent(csec_priv->dev, 32, &k_dma, GFP_KERNEL | GFP_DMA);
	ct= dma_alloc_coherent(csec_priv->dev, 32, &ct_dma, GFP_KERNEL | GFP_DMA);

	if(!ct)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	asym_res = kzalloc(sizeof(struct asym_resource),GFP_KERNEL);
	if(!asym_res)
	{
		csec_error(KERN_INFO "struct asym_resource kzalloc failed\n");
		return -EINVAL;
	}
	memcpy(fp256_param, sm2_fp_param1, 224);
	memcpy(pub_key, s_puba, 64);
	memcpy(msg, standard_mes, 19);
	memcpy(k, rng_k, 32);

	//encrypt	
	st_enc.klen = 19;
	*ct = st_enc.ct = (st_enc.klen + 31)/32;
	st_enc.ecc_dma.p = fp256_param_dma;
	st_enc.ecc_dma.a = fp256_param_dma+32;
	st_enc.ecc_dma.b = fp256_param_dma+32*2;
	st_enc.ecc_dma.gx = fp256_param_dma+32*3;
	st_enc.ecc_dma.gy = fp256_param_dma+32*4;
	st_enc.ecc_dma.n = fp256_param_dma+32*5;
	st_enc.pubkey_dma.x = pub_key_dma;
	st_enc.pubkey_dma.y = pub_key_dma+32;
	st_enc.ciphertext_dma.c1 = c_dma;
	st_enc.ciphertext_dma.c2 = c_dma+1+2*32;
	st_enc.ciphertext_dma.c3 = c_dma+1+2*32+19;
	st_enc.msg_dma = msg_dma;
	st_enc.hashin_dma = hashin_dma;
//	st_enc.hashout_dma = hashout_dma;
	st_enc.ct_dma = ct_dma;
	st_enc.k_dma = k_dma;
	st_enc.plen = 32;
	st_enc.nlen = 32;
	st_enc.ecc_mode = FP;
	st_enc.endian_mode = LITTLE;
	st_enc.rng_mode = CONSTANT;
	
	asym_res->algs = SM2;
	asym_res->type = ENCRYPT; 
	asym_res->sm2_enc_res.fp256_param = fp256_param;
	asym_res->sm2_enc_res.pub_key = pub_key;
	asym_res->sm2_enc_res.msg = msg;
	asym_res->sm2_enc_res.c = c;
	asym_res->sm2_enc_res.hashin = hashin;
	asym_res->sm2_enc_res.k = k;
	asym_res->sm2_enc_res.ct = ct;
	asym_res->sm2_enc_res.fp256_param_dma = fp256_param_dma;
	asym_res->sm2_enc_res.pub_key_dma = pub_key_dma;
	asym_res->sm2_enc_res.msg_dma = msg_dma;
	asym_res->sm2_enc_res.c_dma = c_dma;
	asym_res->sm2_enc_res.hashin_dma = hashin_dma;
	asym_res->sm2_enc_res.k_dma = k_dma;
	asym_res->sm2_enc_res.ct_dma = ct_dma;
	asym_res->sm2_enc_res.fp256_param_len = 224;
	asym_res->sm2_enc_res.pub_key_len = 32*2;
	asym_res->sm2_enc_res.msg_len = 19;
	asym_res->sm2_enc_res.c_len = 1+32*2+19+32;
	asym_res->sm2_enc_res.hashin_len = 32*2+4;
	asym_res->sm2_enc_res.k_len = 32;
	asym_res->sm2_enc_res.ct_len = 32;

	asym_res->comp = para;
	asym_res->sm2_enc_res.ctrl_data = kzalloc(asym_res->sm2_enc_res.c_len, GFP_KERNEL);
	if(!asym_res->sm2_enc_res.ctrl_data)
	{
		csec_error(KERN_INFO "%s: control data buffer kzalloc error\n",__func__);
		return -EINVAL;
	}
	memcpy(asym_res->sm2_enc_res.ctrl_data,cipher_text, asym_res->sm2_enc_res.c_len);

	asym_res->callback = (void *)asym_callback_handler;

	do_sm2_encrypt_asyn(csec_priv, desc, desc_dma, &st_enc, asym_res);

#ifndef ASYN_MODE_BENCHMARK
	complete(this);
#endif
	return 0;
}

int sm2_decrypt_thread_asyn(void *para)
{
	struct sm2_dec_private_dma st_dec;

	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);
	struct asym_resource *asym_res;

	unsigned char standard_mes[19] =
	{
		0x65, 0x6E, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x73,
		0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64
	};
	unsigned char s_pria[32] = {
		0x16, 0x49, 0xAB, 0x77, 0xA0, 0x06, 0x37, 0xBD, 0x5E, 0x2E, 0xFE, 0x28, 0x3F, 0xBF, 0x35, 0x35,
		0x34, 0xAA, 0x7F, 0x7C, 0xB8, 0x94, 0x63, 0xF2, 0x08, 0xDD, 0xBC, 0x29, 0x20, 0xBB, 0x0D, 0xA0	
	};
	unsigned char cipher_text[116] = {
		0x04, 0x24, 0x5C, 0x26, 0xFB, 0x68, 0xB1, 0xDD, 0xDD, 0xB1, 0x2C, 0x4B, 0x6B, 0xF9, 0xF2, 0xB6,
		0xD5, 0xFE, 0x60, 0xA3, 0x83, 0xB0, 0xD1, 0x8D, 0x1C, 0x41, 0x44, 0xAB, 0xF1, 0x7F, 0x62, 0x52,
		0xE7, 0x76, 0xCB, 0x92, 0x64, 0xC2, 0xA7, 0xE8, 0x8E, 0x52, 0xB1, 0x99, 0x03, 0xFD, 0xC4, 0x73, 0x78, 0xF6, 0x05, 0xE3, 0x68, 0x11, 0xF5, 0xC0, 0x74, 0x23, 0xA2, 0x4B, 0x84, 0x40, 0x0F, 0x01,
		0xB8, 0x65, 0x00, 0x53, 0xA8, 0x9B, 0x41, 0xC4, 0x18, 0xB0, 0xC3, 0xAA, 0xD0, 0x0D, 0x88, 0x6C, 0x00, 0x28, 0x64, 0x67, 0x9C, 0x3D, 0x73, 0x60, 0xC3, 0x01, 0x56, 0xFA, 0xB7, 0xC8, 0x0A, 0x02,
		0x76, 0x71, 0x2D, 0xA9, 0xD8, 0x09, 0x4A, 0x63, 0x4B, 0x76, 0x6D, 0x3A, 0x28, 0x5E, 0x07, 0x48, 0x06, 0x53, 0x42, 0x6D
	};

	unsigned char *fp256_param, *pri_key, *msg, *c, *hashin;
//	unsigned char , *hashout;
	unsigned int *desc, *ct;
	dma_addr_t fp256_param_dma, desc_dma, pri_key_dma, msg_dma, c_dma, hashin_dma, ct_dma;

	fp256_param = dma_alloc_coherent(csec_priv->dev, 224, &fp256_param_dma, GFP_KERNEL | GFP_DMA);
	pri_key = dma_alloc_coherent(csec_priv->dev, 32, &pri_key_dma, GFP_KERNEL | GFP_DMA);
	desc = dma_alloc_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, &desc_dma, GFP_KERNEL | GFP_DMA);
	msg = dma_alloc_coherent(csec_priv->dev, 19, &msg_dma, GFP_KERNEL | GFP_DMA);
	c = dma_alloc_coherent(csec_priv->dev, 1+32*2+19+32, &c_dma, GFP_KERNEL | GFP_DMA);
	hashin = dma_alloc_coherent(csec_priv->dev, 32*2+4, &hashin_dma, GFP_KERNEL | GFP_DMA);
	ct= dma_alloc_coherent(csec_priv->dev, 32, &ct_dma, GFP_KERNEL | GFP_DMA);

	if(!ct)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	asym_res = kzalloc(sizeof(struct asym_resource),GFP_KERNEL);
	if(!asym_res)
	{
		csec_error(KERN_INFO "struct asym_resource kzalloc failed\n");
		return -EINVAL;
	}
	memcpy(fp256_param, sm2_fp_param1, 224);
	memcpy(pri_key, s_pria, 32);
	memcpy(c, cipher_text, 116);
	*ct = 1;

	//decrypt
	st_dec.ecc_dma.p = fp256_param_dma;
	st_dec.ecc_dma.a = fp256_param_dma+32;
	st_dec.ecc_dma.b = fp256_param_dma+32*2;
	st_dec.ecc_dma.gx = fp256_param_dma+32*3;
	st_dec.ecc_dma.gy = fp256_param_dma+32*4;
	st_dec.ecc_dma.n = fp256_param_dma+32*5;
	st_dec.ciphertext_dma.c1 = c_dma;
	st_dec.ciphertext_dma.c2 = c_dma+1+2*32;
	st_dec.ciphertext_dma.c3 = c_dma+1+2*32+19;
	st_dec.prikey_dma = pri_key_dma;
	st_dec.msg_dma = msg_dma;
	st_dec.hashin_dma = hashin_dma;
//	st_dec.hashout_dma = hashout_dma;
	st_dec.ct_dma = ct_dma;
	st_dec.plen = 32;
	st_dec.nlen = 32;
	st_dec.klen = 19;
	st_dec.ct = 1;
	st_dec.ecc_mode = FP;
	st_dec.endian_mode = LITTLE;
	
	asym_res->algs = SM2;
	asym_res->type = DECRYPT; 
	asym_res->sm2_dec_res.fp256_param = fp256_param;
	asym_res->sm2_dec_res.pri_key = pri_key;
	asym_res->sm2_dec_res.msg = msg;
	asym_res->sm2_dec_res.c = c;
	asym_res->sm2_dec_res.hashin = hashin;
	asym_res->sm2_dec_res.ct = ct;
	asym_res->sm2_dec_res.fp256_param_dma = fp256_param_dma;
	asym_res->sm2_dec_res.pri_key_dma = pri_key_dma;
	asym_res->sm2_dec_res.msg_dma = msg_dma;
	asym_res->sm2_dec_res.c_dma = c_dma;
	asym_res->sm2_dec_res.hashin_dma = hashin_dma;
	asym_res->sm2_dec_res.ct_dma = ct_dma;
	asym_res->sm2_dec_res.fp256_param_len = 224;
	asym_res->sm2_dec_res.pri_key_len = 32;
	asym_res->sm2_dec_res.msg_len = 19;
	asym_res->sm2_dec_res.c_len = 1+32*2+19+32;
	asym_res->sm2_dec_res.hashin_len = 32*2+4;
	asym_res->sm2_dec_res.ct_len = 32;

	asym_res->comp = para;
	asym_res->sm2_dec_res.ctrl_data = kzalloc(asym_res->sm2_dec_res.msg_len, GFP_KERNEL);
	if(!asym_res->sm2_dec_res.ctrl_data)
	{
		csec_error(KERN_INFO "%s: control data buffer kzalloc failed!\n",__func__);
		return -EINVAL;
	}
	memcpy(asym_res->sm2_dec_res.ctrl_data,
			standard_mes, asym_res->sm2_dec_res.msg_len);
	asym_res->callback = (void *)asym_callback_handler;

	do_sm2_decrypt_asyn(csec_priv, desc, desc_dma, &st_dec, asym_res);
#ifndef ASYN_MODE_BENCHMARK
	complete(this);
#endif
	return 0;
}

int sm2_signature_thread_asyn(void *para)
{
	struct sm2_sig_private_dma st_sig;
	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);
	struct asym_resource *asym_res;

	unsigned char entla[2] = {
		0x00, 0x90
	};
	unsigned char standard_ida[18] =
	{
		0x41, 0x4C, 0x49, 0x43, 0x45, 0x31, 0x32, 0x33, 0x40, 0x59, 0x41, 0x48,
		0x4F, 0x4F, 0x2E, 0x43, 0x4F, 0x4D
	};
	unsigned char standard_mes1[14] =
	{
		0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x64, 0x69, 0x67, 0x65,
		0x73, 0x74
	};
	unsigned char s_pria[32] = {
		0x12, 0x8B, 0x2F, 0xA8, 0xBD, 0x43, 0x3C, 0x6C, 0x06, 0x8C, 0x8D, 0x80, 0x3D, 0xFF, 0x79, 0x79,
		0x2A, 0x51, 0x9A, 0x55, 0x17, 0x1B, 0x1B, 0x65, 0x0C, 0x23, 0x66, 0x1D, 0x15, 0x89, 0x72, 0x63	
	};
	unsigned char s_puba[64] = {
		0x0A, 0xE4, 0xC7, 0x79, 0x8A, 0xA0, 0xF1, 0x19, 0x47, 0x1B, 0xEE, 0x11, 0x82, 0x5B, 0xE4, 0x62,     
		0x02, 0xBB, 0x79, 0xE2, 0xA5, 0x84, 0x44, 0x95, 0xE9, 0x7C, 0x04, 0xFF, 0x4D, 0xF2, 0x54, 0x8A,     
		0x7C, 0x02, 0x40, 0xF8, 0x8F, 0x1C, 0xD4, 0xE1, 0x63, 0x52, 0xA7, 0x3C, 0x17, 0xB7, 0xF1, 0x6F,     
		0x07, 0x35, 0x3E, 0x53, 0xA1, 0x76, 0xD6, 0x84, 0xA9, 0xFE, 0x0C, 0x6B, 0xB7, 0x98, 0xE8, 0x57	
	};
	unsigned char rng_k[32] = {
		0x6C, 0xB2, 0x8D, 0x99, 0x38, 0x5C, 0x17, 0x5C, 0x94, 0xF9, 0x4E, 0x93, 0x48, 0x17, 0x66, 0x3F,
		0xC1, 0x76, 0xD9, 0x25, 0xDD, 0x72, 0xB7, 0x27, 0x26, 0x0D, 0xBA, 0xAE, 0x1F, 0xB2, 0xF9, 0x6F
	};
	unsigned char rs[64] = {
		0x40, 0xF1, 0xEC, 0x59, 0xF7, 0x93, 0xD9, 0xF4, 0x9E, 0x09, 0xDC, 0xEF, 0x49, 0x13, 0x0D, 0x41, 
		0x94, 0xF7, 0x9F, 0xB1, 0xEE, 0xD2, 0xCA, 0xA5, 0x5B, 0xAC, 0xDB, 0x49, 0xC4, 0xE7, 0x55, 0xD1,
		0x6F, 0xC6, 0xDA, 0xC3, 0x2C, 0x5D, 0x5C, 0xF1, 0x0C, 0x77, 0xDF, 0xB2, 0x0F, 0x7C, 0x2E, 0xB6, 
		0x67, 0xA4, 0x57, 0x87, 0x2F, 0xB0, 0x9E, 0xC5, 0x63, 0x27, 0xA6, 0x7E, 0xC7, 0xDE, 0xEB, 0xE7	
	};

	unsigned char *fp256_param, *pri_key, *msg, *r, *s, *one, *z, *k;
	unsigned int *desc;
	dma_addr_t fp256_param_dma, desc_dma, pri_key_dma, msg_dma, r_dma, s_dma, one_dma, z_dma, k_dma;

	fp256_param = dma_alloc_coherent(csec_priv->dev, 224, &fp256_param_dma, GFP_KERNEL | GFP_DMA);
	pri_key = dma_alloc_coherent(csec_priv->dev, 32, &pri_key_dma, GFP_KERNEL | GFP_DMA);
	desc = dma_alloc_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, &desc_dma, GFP_KERNEL | GFP_DMA);
	msg = dma_alloc_coherent(csec_priv->dev, 14, &msg_dma, GFP_KERNEL | GFP_DMA);
	r= dma_alloc_coherent(csec_priv->dev, 32, &r_dma, GFP_KERNEL | GFP_DMA);
	s= dma_alloc_coherent(csec_priv->dev, 32, &s_dma, GFP_KERNEL | GFP_DMA);
	one= dma_alloc_coherent(csec_priv->dev, 32, &one_dma, GFP_KERNEL | GFP_DMA);
	k= dma_alloc_coherent(csec_priv->dev, 32, &k_dma, GFP_KERNEL | GFP_DMA);
	z= dma_alloc_coherent(csec_priv->dev, 2+18+6*32, &z_dma, GFP_KERNEL | GFP_DMA);

	if(!z)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	asym_res = kzalloc(sizeof(struct asym_resource),GFP_KERNEL);
	if(!asym_res)
	{
		csec_error(KERN_INFO "struct asym_resource kzalloc failed\n");
		return -EINVAL;
	}

	memcpy(fp256_param, sm2_fp_param1, 224);
	memcpy(pri_key, s_pria, 32);
	memcpy(msg, standard_mes1, 14);
	memcpy(z, entla, 2);
	memcpy(z+2, standard_ida, 18);
	memcpy(z+2+18, sm2_fp_param1+32, 4*32);
	memcpy(z+2+18+4*32, s_puba, 64);
	memcpy(k, rng_k, 32);

	//signature
	memset(one, 0, 32);
	one[0] = 0x1;
	st_sig.ecc_dma.p = fp256_param_dma;
	st_sig.ecc_dma.a = fp256_param_dma+32;
	st_sig.ecc_dma.b = fp256_param_dma+32*2;
	st_sig.ecc_dma.gx = fp256_param_dma+32*3;
	st_sig.ecc_dma.gy = fp256_param_dma+32*4;
	st_sig.ecc_dma.n = fp256_param_dma+32*5;
	st_sig.sig_dma.r = r_dma;
	st_sig.sig_dma.s = s_dma;
	st_sig.prikey_dma = pri_key_dma;
	st_sig.z_dma = z_dma;
	st_sig.one_dma = one_dma;
	st_sig.k_dma = k_dma;
	st_sig.msg_dma = msg_dma;
	st_sig.plen = 32;
	st_sig.nlen = 32;
	st_sig.klen = 14;
	st_sig.zlen = 2+18+6*32;
	st_sig.ecc_mode = FP;
	st_sig.sig_mode = WITHID;
	st_sig.rng_mode = CONSTANT;
	
	asym_res->algs = SM2;
	asym_res->type = SIGN; 
	asym_res->sm2_sign_res.fp256_param = fp256_param;
	asym_res->sm2_sign_res.pri_key = pri_key;
	asym_res->sm2_sign_res.msg = msg;
	asym_res->sm2_sign_res.r = r;
	asym_res->sm2_sign_res.s = s;
	asym_res->sm2_sign_res.one = one;
	asym_res->sm2_sign_res.k = k;
	asym_res->sm2_sign_res.z = z;
	asym_res->sm2_sign_res.fp256_param_dma = fp256_param_dma;
	asym_res->sm2_sign_res.pri_key_dma = pri_key_dma;
	asym_res->sm2_sign_res.msg_dma = msg_dma;
	asym_res->sm2_sign_res.r_dma = r_dma;
	asym_res->sm2_sign_res.s_dma = s_dma;
	asym_res->sm2_sign_res.one_dma = one_dma;
	asym_res->sm2_sign_res.k_dma = k_dma;
	asym_res->sm2_sign_res.z_dma = z_dma;
	asym_res->sm2_sign_res.fp256_param_len = 224;
	asym_res->sm2_sign_res.pri_key_len = 32;
	asym_res->sm2_sign_res.msg_len = 14;
	asym_res->sm2_sign_res.r_len = 32;
	asym_res->sm2_sign_res.s_len = 32;
	asym_res->sm2_sign_res.one_len = 32;
	asym_res->sm2_sign_res.k_len = 32;
	asym_res->sm2_sign_res.z_len = 2+18+6*32;

	asym_res->comp = para;
	asym_res->sm2_sign_res.ctrl_data = kzalloc(64, GFP_KERNEL);
	if(!asym_res->sm2_sign_res.ctrl_data)
	{
		csec_error(KERN_INFO "%s: control data buffer kzalloc failed!\n",__func__);
		return -EINVAL;
	}
	memcpy(asym_res->sm2_sign_res.ctrl_data,
			rs, 64);
	asym_res->callback = (void *)asym_callback_handler;
	do_sm2_signature_asyn(csec_priv, desc, desc_dma, &st_sig, asym_res);

#ifndef ASYN_MODE_BENCHMARK
	complete(this);
#endif
	return 0;
}

int sm2_verify_thread_asyn(void *para)
{
	struct sm2_ver_private_dma st_ver;

	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);
	struct asym_resource *asym_res;

	unsigned char entla[2] = {
		0x00, 0x90
	};
	unsigned char standard_ida[18] =
	{
		0x41, 0x4C, 0x49, 0x43, 0x45, 0x31, 0x32, 0x33, 0x40, 0x59, 0x41, 0x48,
		0x4F, 0x4F, 0x2E, 0x43, 0x4F, 0x4D
	};
	unsigned char standard_mes1[14] =
	{
		0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x64, 0x69, 0x67, 0x65,
		0x73, 0x74
	};
	unsigned char s_puba[64] = {
		0x0A, 0xE4, 0xC7, 0x79, 0x8A, 0xA0, 0xF1, 0x19, 0x47, 0x1B, 0xEE, 0x11, 0x82, 0x5B, 0xE4, 0x62,     
		0x02, 0xBB, 0x79, 0xE2, 0xA5, 0x84, 0x44, 0x95, 0xE9, 0x7C, 0x04, 0xFF, 0x4D, 0xF2, 0x54, 0x8A,     
		0x7C, 0x02, 0x40, 0xF8, 0x8F, 0x1C, 0xD4, 0xE1, 0x63, 0x52, 0xA7, 0x3C, 0x17, 0xB7, 0xF1, 0x6F,     
		0x07, 0x35, 0x3E, 0x53, 0xA1, 0x76, 0xD6, 0x84, 0xA9, 0xFE, 0x0C, 0x6B, 0xB7, 0x98, 0xE8, 0x57	
	};
	unsigned char rs[64] = {
		0x40, 0xF1, 0xEC, 0x59, 0xF7, 0x93, 0xD9, 0xF4, 0x9E, 0x09, 0xDC, 0xEF, 0x49, 0x13, 0x0D, 0x41, 
		0x94, 0xF7, 0x9F, 0xB1, 0xEE, 0xD2, 0xCA, 0xA5, 0x5B, 0xAC, 0xDB, 0x49, 0xC4, 0xE7, 0x55, 0xD1,
		0x6F, 0xC6, 0xDA, 0xC3, 0x2C, 0x5D, 0x5C, 0xF1, 0x0C, 0x77, 0xDF, 0xB2, 0x0F, 0x7C, 0x2E, 0xB6, 
		0x67, 0xA4, 0x57, 0x87, 0x2F, 0xB0, 0x9E, 0xC5, 0x63, 0x27, 0xA6, 0x7E, 0xC7, 0xDE, 0xEB, 0xE7	
	};

	unsigned char *fp256_param, *pub_key, *msg, *r, *s, *one, *z;
	unsigned int *desc;
	dma_addr_t fp256_param_dma, desc_dma, pub_key_dma, msg_dma, r_dma, s_dma, one_dma, z_dma;

	fp256_param = dma_alloc_coherent(csec_priv->dev, 224, &fp256_param_dma, GFP_KERNEL | GFP_DMA);
	pub_key = dma_alloc_coherent(csec_priv->dev, 64, &pub_key_dma, GFP_KERNEL | GFP_DMA);
	desc = dma_alloc_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, &desc_dma, GFP_KERNEL | GFP_DMA);
	msg = dma_alloc_coherent(csec_priv->dev, 14, &msg_dma, GFP_KERNEL | GFP_DMA);
	r= dma_alloc_coherent(csec_priv->dev, 32, &r_dma, GFP_KERNEL | GFP_DMA);
	s= dma_alloc_coherent(csec_priv->dev, 32, &s_dma, GFP_KERNEL | GFP_DMA);
	one= dma_alloc_coherent(csec_priv->dev, 32, &one_dma, GFP_KERNEL | GFP_DMA);
	z= dma_alloc_coherent(csec_priv->dev, 2+18+6*32, &z_dma, GFP_KERNEL | GFP_DMA);

	if(!z)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	asym_res = kzalloc(sizeof(struct asym_resource),GFP_KERNEL);
	if(!asym_res)
	{
		csec_error(KERN_INFO "struct asym_resource kzalloc failed\n");
		return -EINVAL;
	}

	memcpy(fp256_param, sm2_fp_param1, 224);
	memcpy(pub_key, s_puba, 64);
	memcpy(r, rs, 32);
	memcpy(s, rs+32, 32);
	memcpy(msg, standard_mes1, 14);
	memcpy(z, entla, 2);
	memcpy(z+2, standard_ida, 18);
	memcpy(z+2+18, sm2_fp_param1+32, 4*32);
	memcpy(z+2+18+4*32, s_puba, 64);
	memset(one, 0, 32);
	one[0] = 0x1;

	//verify
	st_ver.ecc_dma.p = fp256_param_dma;
	st_ver.ecc_dma.a = fp256_param_dma+32;
	st_ver.ecc_dma.b = fp256_param_dma+32*2;
	st_ver.ecc_dma.gx = fp256_param_dma+32*3;
	st_ver.ecc_dma.gy = fp256_param_dma+32*4;
	st_ver.ecc_dma.n = fp256_param_dma+32*5;
	st_ver.pubkey_dma.x = pub_key_dma;
	st_ver.pubkey_dma.y = pub_key_dma+32;
	st_ver.sig_dma.r = r_dma;
	st_ver.sig_dma.s = s_dma;
	st_ver.z_dma = z_dma;
	st_ver.one_dma = one_dma;
	st_ver.msg_dma = msg_dma;
	st_ver.plen = 32;
	st_ver.nlen = 32;
	st_ver.klen = 14;
	st_ver.zlen = 2+18+6*32;
	st_ver.ecc_mode = FP;
	st_ver.sig_mode = WITHID;

	asym_res->algs = SM2;
	asym_res->type = VERIFY; 
	asym_res->sm2_veri_res.fp256_param = fp256_param;
	asym_res->sm2_veri_res.pub_key = pub_key;
	asym_res->sm2_veri_res.msg = msg;
	asym_res->sm2_veri_res.r = r;
	asym_res->sm2_veri_res.s = s;
	asym_res->sm2_veri_res.one = one;
	asym_res->sm2_veri_res.z = z;
	asym_res->sm2_veri_res.fp256_param_dma = fp256_param_dma;
	asym_res->sm2_veri_res.pub_key_dma = pub_key_dma;
	asym_res->sm2_veri_res.msg_dma = msg_dma;
	asym_res->sm2_veri_res.r_dma = r_dma;
	asym_res->sm2_veri_res.s_dma = s_dma;
	asym_res->sm2_veri_res.one_dma = one_dma;
	asym_res->sm2_veri_res.z_dma = z_dma;
	asym_res->sm2_veri_res.fp256_param_len = 224;
	asym_res->sm2_veri_res.pub_key_len = 64;
	asym_res->sm2_veri_res.msg_len = 14;
	asym_res->sm2_veri_res.r_len = 32;
	asym_res->sm2_veri_res.s_len = 32;
	asym_res->sm2_veri_res.one_len = 32;
	asym_res->sm2_veri_res.z_len = 2+18+6*32;
	asym_res->comp = para;

	asym_res->callback = (void *)asym_callback_handler;

	do_sm2_verify_asyn(csec_priv, desc, desc_dma, &st_ver, asym_res);
#ifndef ASYN_MODE_BENCHMARK
	complete(this);
#endif
	return 0;
}

int sm2_exchange_thread_asyn(void *para)
{
	struct sm2_exc_private_dma st_exc;

	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);
	struct asym_resource *asym_res;

	unsigned char entla[2] = {
		0x00, 0x90
	};
	unsigned char s_ida[18] = {
		0x41, 0x4C, 0x49, 0x43, 0x45, 0x31, 0x32, 0x33, 0x40, 0x59, 0x41, 0x48, 0x4F, 0x4F, 0x2E, 0x43, 0x4F, 0x4D	
	};
	unsigned char entlb[2] = {
		0x00, 0x88
	};
	unsigned char s_idb[17] = {
		0x42, 0x49, 0x4C, 0x4C, 0x34, 0x35, 0x36, 0x40, 0x59, 0x41, 0x48, 0x4F, 0x4F, 0x2E, 0x43, 0x4F, 0x4D	
	};
	unsigned char s_pria[32] = {
		0x6F, 0xCB, 0xA2, 0xEF, 0x9A, 0xE0, 0xAB, 0x90, 0x2B, 0xC3, 0xBD, 0xE3, 0xFF, 0x91, 0x5D, 0x44, 
		0xBA, 0x4C, 0xC7, 0x8F, 0x88, 0xE2, 0xF8, 0xE7, 0xF8, 0x99, 0x6D, 0x3B, 0x8C, 0xCE, 0xED, 0xEE	
	};
	unsigned char s_puba[64] = {                                                                                      
		0x30, 0x99, 0x09, 0x3B, 0xF3, 0xC1, 0x37, 0xD8, 0xFC, 0xBB, 0xCD, 0xF4, 0xA2, 0xAE, 0x50, 0xF3,           
		0xB0, 0xF2, 0x16, 0xC3, 0x12, 0x2D, 0x79, 0x42, 0x5F, 0xE0, 0x3A, 0x45, 0xDB, 0xFE, 0x16, 0x55,           
		0x3D, 0xF7, 0x9E, 0x8D, 0xAC, 0x1C, 0xF0, 0xEC, 0xBA, 0xA2, 0xF2, 0xB4, 0x9D, 0x51, 0xA4, 0xB3,           
		0x87, 0xF2, 0xEF, 0xAF, 0x48, 0x23, 0x39, 0x08, 0x6A, 0x27, 0xA8, 0xE0, 0x5B, 0xAE, 0xD9, 0x8B	   
	};
	unsigned char s_pubb[64] = {
		0x24, 0x54, 0x93, 0xD4, 0x46, 0xC3, 0x8D, 0x8C, 0xC0, 0xF1, 0x18, 0x37, 0x46, 0x90, 0xE7, 0xDF, 
		0x63, 0x3A, 0x8A, 0x4B, 0xFB, 0x33, 0x29, 0xB5, 0xEC, 0xE6, 0x04, 0xB2, 0xB4, 0xF3, 0x7F, 0x43,
		0x53, 0xC0, 0x86, 0x9F, 0x4B, 0x9E, 0x17, 0x77, 0x3D, 0xE6, 0x8F, 0xEC, 0x45, 0xE1, 0x49, 0x04, 
		0xE0, 0xDE, 0xA4, 0x5B, 0xF6, 0xCE, 0xCF, 0x99, 0x18, 0xC8, 0x5E, 0xA0, 0x47, 0xC6, 0x0A, 0x4C
	};
	unsigned char s_tpria[32] = {
		0x83, 0xA2, 0xC9, 0xC8, 0xB9, 0x6E, 0x5A, 0xF7, 0x0B, 0xD4, 0x80, 0xB4, 0x72, 0x40, 0x9A, 0x9A, 
		0x32, 0x72, 0x57, 0xF1, 0xEB, 0xB7, 0x3F, 0x5B, 0x07, 0x33, 0x54, 0xB2, 0x48, 0x66, 0x85, 0x63	
	};
	unsigned char s_tpuba[64] = {
		0x6C, 0xB5, 0x63, 0x38, 0x16, 0xF4, 0xDD, 0x56, 0x0B, 0x1D, 0xEC, 0x45, 0x83, 0x10, 0xCB, 0xCC, 
		0x68, 0x56, 0xC0, 0x95, 0x05, 0x32, 0x4A, 0x6D, 0x23, 0x15, 0x0C, 0x40, 0x8F, 0x16, 0x2B, 0xF0,
		0x0D, 0x6F, 0xCF, 0x62, 0xF1, 0x03, 0x6C, 0x0A, 0x1B, 0x6D, 0xAC, 0xCF, 0x57, 0x39, 0x92, 0x23, 
		0xA6, 0x5F, 0x7D, 0x7B, 0xF2, 0xD9, 0x63, 0x7E, 0x5B, 0xBB, 0xEB, 0x85, 0x79, 0x61, 0xBF, 0x1A	
	};
	unsigned char s_tpubb[64] = {
		0x17, 0x99, 0xB2, 0xA2, 0xC7, 0x78, 0x29, 0x53, 0x00, 0xD9, 0xA2, 0x32, 0x5C, 0x68, 0x61, 0x29, 
		0xB8, 0xF2, 0xB5, 0x33, 0x7B, 0x3D, 0xCF, 0x45, 0x14, 0xE8, 0xBB, 0xC1, 0x9D, 0x90, 0x0E, 0xE5,	
		0x54, 0xC9, 0x28, 0x8C, 0x82, 0x73, 0x3E, 0xFD, 0xF7, 0x80, 0x8A, 0xE7, 0xF2, 0x7D, 0x0E, 0x73, 
		0x2F, 0x7C, 0x73, 0xA7, 0xD9, 0xAC, 0x98, 0xB7, 0xD8, 0x74, 0x0A, 0x91, 0xD0, 0xDB, 0x3C, 0xF4
	};
	unsigned char sb[32] = {
		0x28, 0x4C, 0x8F, 0x19, 0x8F, 0x14, 0x1B, 0x50, 0x2E, 0x81, 0x25, 0x0F, 0x15, 0x81, 0xC7, 0xE9,
		0xEE, 0xB4, 0xCA, 0x69, 0x90, 0xF9, 0xE0, 0x2D, 0xF3, 0x88, 0xB4, 0x54, 0x71, 0xF5, 0xBC, 0x5C
	};
	unsigned char sa[32] = {
		0x23, 0x44, 0x4D, 0xAF, 0x8E, 0xD7, 0x53, 0x43, 0x66, 0xCB, 0x90, 0x1C, 0x84, 0xB3, 0xBD, 0xBB,
		0x63, 0x50, 0x4F, 0x40, 0x65, 0xC1, 0x11, 0x6C, 0x91, 0xA4, 0xC0, 0x06, 0x97, 0xE6, 0xCF, 0x7A
	};
	
	unsigned char *fp256_param, *pri_key, *hashin, *hashout, *one, *pub_key1, *tmp_pub_key, *tmp_pri_key, *tmp_pub_key1, *x1, *x2, *z1, *z2, *key, *s1, *s2, *za, *zb;
	unsigned int *desc, *ct;
	dma_addr_t fp256_param_dma, desc_dma, pri_key_dma, hashin_dma, hashout_dma, ct_dma, one_dma, pub_key1_dma, tmp_pub_key_dma, tmp_pri_key_dma, tmp_pub_key1_dma, x1_dma, x2_dma, z1_dma, z2_dma, key_dma, s1_dma, s2_dma, za_dma, zb_dma;

	fp256_param = dma_alloc_coherent(csec_priv->dev, 224, &fp256_param_dma, GFP_KERNEL | GFP_DMA);
	pri_key = dma_alloc_coherent(csec_priv->dev, 32, &pri_key_dma, GFP_KERNEL | GFP_DMA);
	desc = dma_alloc_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE*2, &desc_dma, GFP_KERNEL | GFP_DMA);
	hashin = dma_alloc_coherent(csec_priv->dev, 32*2+4, &hashin_dma, GFP_KERNEL | GFP_DMA);
	hashout= dma_alloc_coherent(csec_priv->dev, 128, &hashout_dma, GFP_KERNEL | GFP_DMA);
	ct= dma_alloc_coherent(csec_priv->dev, 32, &ct_dma, GFP_KERNEL | GFP_DMA);
	one= dma_alloc_coherent(csec_priv->dev, 32, &one_dma, GFP_KERNEL | GFP_DMA);
	pub_key1 = dma_alloc_coherent(csec_priv->dev, 32*2, &pub_key1_dma, GFP_KERNEL | GFP_DMA);
	tmp_pub_key = dma_alloc_coherent(csec_priv->dev, 32*2, &tmp_pub_key_dma, GFP_KERNEL | GFP_DMA);
	tmp_pri_key = dma_alloc_coherent(csec_priv->dev, 32, &tmp_pri_key_dma, GFP_KERNEL | GFP_DMA);
	tmp_pub_key1 = dma_alloc_coherent(csec_priv->dev, 32*2, &tmp_pub_key1_dma, GFP_KERNEL | GFP_DMA);
	x1 = dma_alloc_coherent(csec_priv->dev, 32, &x1_dma, GFP_KERNEL | GFP_DMA);
	x2 = dma_alloc_coherent(csec_priv->dev, 32, &x2_dma, GFP_KERNEL | GFP_DMA);
	z1 = dma_alloc_coherent(csec_priv->dev, 2+18+6*32, &z1_dma, GFP_KERNEL | GFP_DMA);
	z2 = dma_alloc_coherent(csec_priv->dev, 2+17+6*32, &z2_dma, GFP_KERNEL | GFP_DMA);
	za = dma_alloc_coherent(csec_priv->dev, 32, &za_dma, GFP_KERNEL | GFP_DMA);
	zb = dma_alloc_coherent(csec_priv->dev, 32, &zb_dma, GFP_KERNEL | GFP_DMA);
	key = dma_alloc_coherent(csec_priv->dev, 16, &key_dma, GFP_KERNEL | GFP_DMA);
	s1 = dma_alloc_coherent(csec_priv->dev, 32, &s1_dma, GFP_KERNEL | GFP_DMA);
	s2 = dma_alloc_coherent(csec_priv->dev, 32, &s2_dma, GFP_KERNEL | GFP_DMA);
	if(!s2)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	asym_res = kzalloc(sizeof(struct asym_resource),GFP_KERNEL);
	if(!asym_res)
	{
		csec_error(KERN_INFO "struct asym_resource kzalloc failed\n");
		return -EINVAL;
	}

	memcpy(fp256_param, sm2_fp_param1, 224);
	memcpy(pri_key, s_pria, 32);
	memcpy(pub_key1, s_pubb, 64);
	memcpy(tmp_pub_key, s_tpuba, 64);
	memcpy(tmp_pri_key, s_tpria, 32);
	memcpy(tmp_pub_key1, s_tpubb, 64);
	memcpy(z1, entla, 2);
	memcpy(z1+2, s_ida, 18);
	memcpy(z1+2+18, sm2_fp_param1+32, 4*32);
	memcpy(z1+2+18+4*32, s_puba, 64);
	memcpy(z2, entlb, 2);
	memcpy(z2+2, s_idb, 17);
	memcpy(z2+2+17, sm2_fp_param1+32, 4*32);
	memcpy(z2+2+17+4*32, s_pubb, 64);

	memset(x1, 0, 16);
	memset(x2, 0, 16);
	memcpy(x1+16, tmp_pub_key+16, 16);
	memcpy(x2+16, tmp_pub_key1+16, 16);
	x1[16] |= 0x80;
	x2[16] |= 0x80;
	one[0] = 0x2;
	one[1] = 0x3;
	st_exc.ecc_dma.p = fp256_param_dma;
	st_exc.ecc_dma.a = fp256_param_dma+32;
	st_exc.ecc_dma.b = fp256_param_dma+32*2;
	st_exc.ecc_dma.gx = fp256_param_dma+32*3;
	st_exc.ecc_dma.gy = fp256_param_dma+32*4;
	st_exc.ecc_dma.n = fp256_param_dma+32*5;
	st_exc.h_dma = fp256_param_dma+32*6;
	st_exc.self_tmp_pubkey_dma.x = tmp_pub_key_dma;
	st_exc.self_tmp_pubkey_dma.y = tmp_pub_key_dma+32;
	st_exc.other_pubkey_dma.x = pub_key1_dma;
	st_exc.other_pubkey_dma.y = pub_key1_dma+32;
	st_exc.other_tmp_pubkey_dma.x = tmp_pub_key1_dma;
	st_exc.other_tmp_pubkey_dma.y = tmp_pub_key1_dma+32;
	st_exc.u_dma.x = hashin_dma;
	st_exc.u_dma.y = hashin_dma+32;
	st_exc.self_prikey_dma = pri_key_dma;
	st_exc.self_tmp_prikey_dma = tmp_pri_key_dma;
	st_exc.self_x_dma = x1_dma;
	st_exc.other_x_dma = x2_dma;
	st_exc.zain_dma = z1_dma;
	st_exc.zbin_dma = z2_dma;
	st_exc.za_dma = za_dma;
	st_exc.zb_dma = zb_dma;
	st_exc.ct_dma = ct_dma;
	st_exc.key_dma = key_dma;
	st_exc.hashout_dma = hashout_dma;
	st_exc.s1_dma = s1_dma;
	st_exc.s2_dma = s2_dma;
	st_exc.s1_head_dma = one_dma;
	st_exc.s2_head_dma = one_dma+1;
	st_exc.desc_dma = desc_dma;
	st_exc.plen = 32;
	st_exc.nlen = 32;
	st_exc.klen = 16;
	st_exc.zain_len = 2+18+6*32;
	st_exc.zbin_len = 2+17+6*32;
	st_exc.ecc_mode = FP;
	st_exc.endian_mode = LITTLE;
	st_exc.id_mode = WITHID;
	st_exc.exc_mode = A;

	asym_res->algs = SM2;
	asym_res->type = EXCH; 
	asym_res->sm2_exch_res.fp256_param = fp256_param;
	asym_res->sm2_exch_res.pri_key = pri_key;
	asym_res->sm2_exch_res.hashin = hashin;
	asym_res->sm2_exch_res.hashout = hashout;
	asym_res->sm2_exch_res.ct = ct;
	asym_res->sm2_exch_res.one = one;
	asym_res->sm2_exch_res.pub_key1 = pub_key1;
	asym_res->sm2_exch_res.tmp_pub_key = tmp_pub_key;
	asym_res->sm2_exch_res.tmp_pri_key = tmp_pri_key;
	asym_res->sm2_exch_res.tmp_pub_key1= tmp_pub_key1;
	asym_res->sm2_exch_res.x1 = x1;
	asym_res->sm2_exch_res.x2 = x2;
	asym_res->sm2_exch_res.z1 = z1;
	asym_res->sm2_exch_res.z2 = z2;
	asym_res->sm2_exch_res.za = za;
	asym_res->sm2_exch_res.zb = zb;
	asym_res->sm2_exch_res.key = key;
	asym_res->sm2_exch_res.s1 = s1;
	asym_res->sm2_exch_res.s2 = s2;
	asym_res->sm2_exch_res.fp256_param_dma = fp256_param_dma;
	asym_res->sm2_exch_res.pri_key_dma = pri_key_dma;
	asym_res->sm2_exch_res.hashin_dma = hashin_dma;
	asym_res->sm2_exch_res.hashout_dma = hashout_dma;
	asym_res->sm2_exch_res.ct_dma = ct_dma;
	asym_res->sm2_exch_res.one_dma = one_dma;
	asym_res->sm2_exch_res.pub_key1_dma = pub_key1_dma;
	asym_res->sm2_exch_res.tmp_pub_key_dma = tmp_pub_key_dma;
	asym_res->sm2_exch_res.tmp_pri_key_dma = tmp_pri_key_dma;
	asym_res->sm2_exch_res.tmp_pub_key1_dma = tmp_pub_key1_dma;
	asym_res->sm2_exch_res.x1_dma = x1_dma;
	asym_res->sm2_exch_res.x2_dma = x2_dma;
	asym_res->sm2_exch_res.z1_dma = z1_dma;
	asym_res->sm2_exch_res.z2_dma = z2_dma;
	asym_res->sm2_exch_res.za_dma = za_dma;
	asym_res->sm2_exch_res.zb_dma = zb_dma;
	asym_res->sm2_exch_res.key_dma = key_dma;
	asym_res->sm2_exch_res.s1_dma = s1_dma;
	asym_res->sm2_exch_res.s2_dma = s2_dma;
	asym_res->sm2_exch_res.fp256_param_len = 224;
	asym_res->sm2_exch_res.pri_key_len = 32;
	asym_res->sm2_exch_res.hashin_len = 32*2+4;
	asym_res->sm2_exch_res.hashout_len = 128;
	asym_res->sm2_exch_res.ct_len = 32;
	asym_res->sm2_exch_res.one_len = 32;
	asym_res->sm2_exch_res.pub_key1_len = 32*2;
	asym_res->sm2_exch_res.tmp_pub_key_len = 32*2;
	asym_res->sm2_exch_res.tmp_pri_key_len = 32;
	asym_res->sm2_exch_res.tmp_pub_key1_len = 32*2;
	asym_res->sm2_exch_res.x1_len = 32;
	asym_res->sm2_exch_res.x2_len = 32;
	asym_res->sm2_exch_res.z1_len = 2+18+6*32;
	asym_res->sm2_exch_res.z2_len = 2+17+6*32;
	asym_res->sm2_exch_res.za_len = 32;
	asym_res->sm2_exch_res.zb_len = 32;
	asym_res->sm2_exch_res.key_len = 16;
	asym_res->sm2_exch_res.s1_len = 32;
	asym_res->sm2_exch_res.s2_len = 32;

	asym_res->comp = para;
	asym_res->sm2_exch_res.ctrl_data = kzalloc(64, GFP_KERNEL);
	if(!asym_res->sm2_exch_res.ctrl_data)
	{
		csec_error(KERN_INFO "%s: control data buffer kzalloc failed!\n",__func__);
		return -EINVAL;
	}
	memcpy(asym_res->sm2_exch_res.ctrl_data, sb, 32);
	memcpy(asym_res->sm2_exch_res.ctrl_data+32, sa, 32);
	asym_res->callback = (void *)asym_callback_handler;

	do_sm2_exchange_asyn(csec_priv, desc, desc_dma, &st_exc, asym_res);
#ifndef ASYN_MODE_BENCHMARK
	complete(this);
#endif
	return 0;
}
void sm2_multi_test_asyn(void)
{
	int i;
	struct timespec timeinfo;
	unsigned long start_tm_s = 0;
	unsigned long start_tm_us = 0;
	unsigned long finish_tm_s = 0;
	unsigned long finish_tm_us = 0;
	struct task_struct *thread[THREADS_NUM];
	
	/*
	 * SM2 Generate Key
	 */
	for (i=0; i<THREADS_NUM; i++)
	{
		init_completion(&(sym_comp[i]));
	}
	
	
	getnstimeofday(&timeinfo);
	start_tm_s = timeinfo.tv_sec;
	start_tm_us = timeinfo.tv_nsec;

	for(i=0; i<THREADS_NUM; i++)
	{
		thread[i] = kthread_run(sm2_genkey_thread_asyn, &(sym_comp[i]), "sym_thread_asyn");
		if (IS_ERR(thread[i]))
		{
			printk(KERN_ERR "%s: thread %d create failed\n", __func__, i);
		}
	}
	
	for (i=0; i<THREADS_NUM; i++)
	{
		wait_for_completion(&(sym_comp[i]));
	}
	getnstimeofday(&timeinfo);
	finish_tm_s = timeinfo.tv_sec;
	finish_tm_us = timeinfo.tv_nsec;

#ifdef ASYN_MODE_BENCHMARK
	//printk(KERN_ERR "sm2_genkey cost %ld us\n", (finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us);
	printk(KERN_ERR "sm2_genkey speed %ld times/s\n", THREADS_NUM*1000000/((finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us));
#endif
	/*
	 * SM2 Encrypt
	 */
	for (i=0; i<THREADS_NUM; i++)
	{
		init_completion(&(sym_comp[i]));
	}
	
	getnstimeofday(&timeinfo);
	start_tm_s = timeinfo.tv_sec;
	start_tm_us = timeinfo.tv_nsec;

	for(i=0; i<THREADS_NUM; i++)
	{
		thread[i] = kthread_run(sm2_encrypt_thread_asyn, &(sym_comp[i]), "sym_thread_asyn");
		if (IS_ERR(thread[i]))
		{
			printk(KERN_ERR "%s: thread %d create failed\n", __func__, i);
		}
	}
	
	for (i=0; i<THREADS_NUM; i++)
	{
		wait_for_completion(&(sym_comp[i]));
	}

	getnstimeofday(&timeinfo);
	finish_tm_s = timeinfo.tv_sec;
	finish_tm_us = timeinfo.tv_nsec;
	
#ifdef ASYN_MODE_BENCHMARK
	//printk(KERN_ERR "sm2_encrypt cost %ld us\n", (finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us);
	printk(KERN_ERR "sm2_encrypt speed %ld times/s\n", THREADS_NUM*1000000/((finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us));
	
#endif
	/*
	 * SM2 Decrypt
	 */
	for (i=0; i<THREADS_NUM; i++)
	{
		init_completion(&(sym_comp[i]));
	}
	
	getnstimeofday(&timeinfo);
	start_tm_s = timeinfo.tv_sec;
	start_tm_us = timeinfo.tv_nsec;

	for(i=0; i<THREADS_NUM; i++)
	{
		thread[i] = kthread_run(sm2_decrypt_thread_asyn, &(sym_comp[i]), "sym_thread_asyn");
		if (IS_ERR(thread[i]))
		{
			printk(KERN_ERR "%s: thread %d create failed\n", __func__, i);
		}
	}
	
	for (i=0; i<THREADS_NUM; i++)
	{
		wait_for_completion(&(sym_comp[i]));
	}
	
	getnstimeofday(&timeinfo);
	finish_tm_s = timeinfo.tv_sec;
	finish_tm_us = timeinfo.tv_nsec;
	
#ifdef ASYN_MODE_BENCHMARK
	//printk(KERN_ERR "sm2_decrypt cost %ld us\n", (finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us);
	printk(KERN_ERR "sm2_decrypt speed %ld times/s\n", THREADS_NUM*1000000/((finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us));
#endif

	/*
	 * SM2 Signature
	 */
	for (i=0; i<THREADS_NUM; i++)
	{
		init_completion(&(sym_comp[i]));
	}
	
	getnstimeofday(&timeinfo);
	start_tm_s = timeinfo.tv_sec;
	start_tm_us = timeinfo.tv_nsec;
	
	for(i=0; i<THREADS_NUM; i++)
	{
		thread[i] = kthread_run(sm2_signature_thread_asyn, &(sym_comp[i]), "sym_thread_asyn");
		if (IS_ERR(thread[i]))
		{
			printk(KERN_ERR "%s: thread %d create failed\n", __func__, i);
		}
	}
	
	for (i=0; i<THREADS_NUM; i++)
	{
		wait_for_completion(&(sym_comp[i]));
	}
	
	getnstimeofday(&timeinfo);
	finish_tm_s = timeinfo.tv_sec;
	finish_tm_us = timeinfo.tv_nsec;
	
#ifdef ASYN_MODE_BENCHMARK
	//printk(KERN_ERR "sm2_signature cost %ld us\n", (finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us);
	printk(KERN_ERR "sm2_signature speed %ld times/s\n", THREADS_NUM*1000000/((finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us));
#endif

	/*
	 * SM2 Verify 
	 */
	for (i=0; i<THREADS_NUM; i++)
	{
		init_completion(&(sym_comp[i]));
	}
	
	getnstimeofday(&timeinfo);
	start_tm_s = timeinfo.tv_sec;
	start_tm_us = timeinfo.tv_nsec;
	
	for(i=0; i<THREADS_NUM; i++)
	{
		thread[i] = kthread_run(sm2_verify_thread_asyn, &(sym_comp[i]), "sym_thread_asyn");
		if (IS_ERR(thread[i]))
		{
			printk(KERN_ERR "%s: thread %d create failed\n", __func__, i);
		}
	}
	
	for (i=0; i<THREADS_NUM; i++)
	{
		wait_for_completion(&(sym_comp[i]));
	}
	
	getnstimeofday(&timeinfo);
	finish_tm_s = timeinfo.tv_sec;
	finish_tm_us = timeinfo.tv_nsec;
	
#ifdef ASYN_MODE_BENCHMARK
	//printk(KERN_ERR "sm2_verify cost %ld us\n", (finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us);
	printk(KERN_ERR "sm2_verify speed %ld times/s\n", THREADS_NUM*1000000/((finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us));
#endif

	/*
	 * SM2 Exchange 
	 */
	for (i=0; i<THREADS_NUM; i++)
	{
		init_completion(&(sym_comp[i]));
	}
	
	getnstimeofday(&timeinfo);
	start_tm_s = timeinfo.tv_sec;
	start_tm_us = timeinfo.tv_nsec;
	
	for(i=0; i<THREADS_NUM; i++)
	{
		thread[i] = kthread_run(sm2_exchange_thread_asyn, &(sym_comp[i]), "sym_thread_asyn");
		if (IS_ERR(thread[i]))
		{
			printk(KERN_ERR "%s: thread %d create failed\n", __func__, i);
		}
	}
	
	for (i=0; i<THREADS_NUM; i++)
	{
		wait_for_completion(&(sym_comp[i]));
	}
	
	getnstimeofday(&timeinfo);
	finish_tm_s = timeinfo.tv_sec;
	finish_tm_us = timeinfo.tv_nsec;
	
#ifdef ASYN_MODE_BENCHMARK
	//printk(KERN_ERR "sm2_exchange cost %ld us\n", (finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us);
	printk(KERN_ERR "sm2_exchange speed %ld times/s\n", THREADS_NUM*1000000/((finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us));
#endif
	
}
